import React, { PureComponent } from 'react';
import './index.less';
import { connect } from 'dva';
import { Tree, notification } from 'antd';
import { worker } from "../../utils/worker"
import {cloneDeep} from "lodash"
const { TreeNode } = Tree;

class ProjectDirecTree extends PureComponent {
    constructor(props) {
        super(props);
        this.state = { loadedKeys: [], checkedKeys: [], selectedKeys: [], expandedKeys: [], autoExpandParent: true }
        this.onLoad = this.onLoad.bind(this)
        this.loadData = this.loadData.bind(this)
        this.renderTreeNodes = this.renderTreeNodes.bind(this)
        this.insertTreeNode = this.insertTreeNode.bind(this)
        this.updateTreeNode = this.updateTreeNode.bind(this)
        this.getIconByType = this.getIconByType.bind(this)
        this.removeTreeNode = this.removeTreeNode.bind(this)
        this.onExpand = this.onExpand.bind(this)
        this.getTargetNodes = this.getTargetNodes.bind(this)
        this.updateTreeNodeSelf = this.updateTreeNodeSelf.bind(this)
        this.loopTreeNode = this.loopTreeNode.bind(this)
    }
    onSelect = (keys, e) => {
        let dataRef = e.node.props.dataRef
        let eventType;
        if (dataRef) {
            eventType = dataRef.eventType
        } else {
            dataRef = e.node.props
            eventType = dataRef.eventType
        }
        this.setState({
            selectedKeys: keys
        })
        var cache = [];
        let dataRefC = JSON.parse(JSON.stringify(dataRef, function (key, value) {
            if (typeof value === 'object' && value !== null) {
                if (cache.indexOf(value) !== -1) {
                    // Circular reference found, discard key
                    return;
                }
                // Store value in our collection
                cache.push(value);
            }
            return value;
        }))
        cache = null;
        if (eventType == "projectInfo" || eventType == "projectSet") {
            if (this.props.goInnerPage) {
                this.props.goInnerPage(null, '', '项目信息')
            }

        } else if (eventType == 'groupRoads') {//道路数据
            this.props.goInnerPage(null, 'roadDesign', '道路设计')
        } else if (eventType == 'bridgeData') {//道路数据
            this.props.goInnerPage(null, 'bridgeMainList', '桥梁设计')
        } else if (eventType == 'group_road_unit') {//道路
            this.props.goInnerPage(null, "uploadRoads", "路线编辑", { code: "edit", roadId: dataRef.id })
        }
        else if (eventType == 'bridge') {
            // if (dataRef.bridgeScope == 19) {

            //     if (this.props.goInnerPage) {
            //         this.props.goInnerPage(null, 'editBridge', '桥梁 : ' + dataRef.name, bridge)
            //     }
            // } else {
            const bridge = dataRefC
            this.props.updateCurrentBridge(bridge)
            this.props.goInnerPage(null, 'bridgeChildList', '桥梁 : ' + dataRef.name, { bridgeMainId: dataRef.id })
            // }

        } else if (eventType == 'bridgeChild') {
            const bridge = dataRefC
            this.props.updateCurrentBridge(bridge)
            if (this.props.goInnerPage) {
                this.props.goInnerPage(null, 'editBridge', '桥梁 : ' + dataRef.name, dataRefC)
            }
        } else if (eventType == 'topStructure') {
            if (this.props.goInnerPage) {
                this.props.goInnerPage(null, 'topStructure', "上部结构", dataRefC)
            }
        } else if (eventType == 'botStructure') {
            if (this.props.goInnerPage) {
                this.props.goInnerPage(null, 'botStructure', "下部结构", dataRefC)
            }
        } else if (eventType == 'topStructureDirec') {
            if (this.props.goInnerPage) {
                this.props.goInnerPage(null, 'sectionComponents', "联构件列表", dataRefC)
            }
        } else if (eventType == 'botStructureDirec') {
            if (this.props.goInnerPage) {
                this.props.goInnerPage(null, 'pierComponents', "桩构件列表", dataRefC)
            }
        } else if (eventType == 'topStructureComponentUnit') {
            if (this.props.goInnerPage) {
                const obj = dataRefC
                obj.type = "top"
                this.props.goInnerPage(null, 'componentEdit', dataRef.instanceName, obj)
            }
        } else if (eventType == 'botStructureComponentUnit') {
            if (this.props.goInnerPage) {
                const obj = dataRefC
                obj.type = "bottom"
                this.props.goInnerPage(null, 'componentEdit', dataRef.instanceName, obj)
            }
        } else if (dataRef.roadId) {
            this.props.getRoadId(dataRef.roadId)
            if (this.props.goInnerPage) {
                this.props.goInnerPage(null, 'OtherLines' + dataRef.eventType, dataRef.eventType, { roadId: dataRef.roadId })
            }
        }

    };
    loopTreeNode(data) {
        let _this = this;
        function loop(list) {
            if (list && list.length) {
                const len = list.length;
                for (let i = 0; i < len; i++) {
                    let item = list[i]
                    let imgsrc
                    if (item && item.eventType) {
                        imgsrc = _this.getIconByType(item.eventType)
                        item.icon = <img src={imgsrc} alt="" />
                    } else {
                        imgsrc = "./static/images/libary.png"
                    }


                    if (item && item.children && item.children.length) {
                        loop(item.children)
                    } else {
                        continue;
                    }
                }

            }
            return list;
        }
        return loop(data)
    }
    async loadData(e) {
        let _this = this
        let props = this.props
        let { loadedKeys } = this.state;
        let { project, structureTree } = this.props;
        return new Promise(async (resolve, reject) => {
            let { eventType, dataRef } = e.props
            let key = e.key;
            if (!loadedKeys.includes(key)) {
                loadedKeys.push(key)
            }
            if (e.props.children && e.props.children.length) {
                resolve()
                return;
            }
            if (!dataRef) {
                dataRef = cloneDeep(e.props)
                dataRef.rg = true;
                delete dataRef.context
            }

            if (eventType == 'projectSet') {//项目设置

            } else if (eventType == 'groupRoads') {//道路数据
                if (project) {
                    let res = await props.loadRefProjectRoads({ projectId: project.id })
                    if (res && res.length) {
                        const len1 = res.length
                        for (let i = 0; i < len1; i++) {
                            let item = res[i];
                            item.title = '道路 : ' + item.name;
                            item.key = 'group_road_unit' + item.id;
                            item.eventType = 'group_road_unit'
                            item.eventKey = 'group_road_unit'
                            item.checkable = false

                        }
                    }
                    dataRef.children = res
                    // _this.setState({
                    //     data: [..._this.state.data]
                    // })
                    if (dataRef.rg) {
                        _this.updateTreeNode(dataRef.eventKey,res)
                     }
                } else {
                    notification.warn({ message: "请选择项目!" });

                }
                

            } else if (eventType == 'group_road_unit') {//桥梁数据
                let res = await this.props.RoadlineOriginData({ roadlineId: dataRef.id })
                let arr = []
                if (res && res.length) {
                    const len2 = res.length
                    for (let i = 0; i < len2; i++) {
                        let item = res[i];
                        arr.push({
                            roadId: dataRef.id, title: item.attrName, checkable: false, isLeaf: true, eventType: item.attrName, eventKey: item.attrName, key: item.attrName + dataRef.id,
                            children: null
                        })
                    }
                }
                dataRef.children = arr
                // _this.setState({
                //     data: [..._this.state.data]
                // })
            } else if (eventType == 'bridgeData') {//桥梁数据

                if (props.project) {
                    let res = await props.getBridgeMainList({ projectId: props.project.id })
                    if (res && res.length) {
                        const len3 = res.length
                        for (let i = 0; i < len3; i++) {
                            let item = res[i];
                            item.title = ' 桥梁 : ' + item.name;
                            item.key = 'bridge' + item.id;
                            item.eventType = 'bridge'
                            item.eventKey = 'bridge'
                            item.checkable = false
                        }
                    }
                    dataRef.children = res
                    if (dataRef.rg) {
                        _this.updateTreeNode(dataRef.eventKey,res)
                     }
                    // _this.setState({
                    //     data: [..._this.state.data]
                    // })

                } else {
                    notification.warn({ message: "请选择项目!" });
                }

            } else if (eventType == 'bridge') {//单个桥梁数据
                // await props.queryBridgeDetail({ id: dataRef.id })
                // if (dataRef.bridgeScope == 19) {
                //     dataRef.children = [{
                //         title: '上部结构', checkable: false, eventType: 'topStructure', eventKey: 'topStructure', key: 'topStructure' + dataRef.id, bridgeId: dataRef.bridgeId,
                //         children: null
                //     }, {
                //         title: '下部结构', checkable: false, eventType: 'botStructure', eventKey: 'botStructure', key: 'botStructure' + dataRef.id, bridgeId: dataRef.bridgeId,
                //         children: null
                //     }, {
                //         title: '附属结构', checkable: false, eventType: 'attachStructure', eventKey: 'attachStructure', key: 'attachStructure' + dataRef.id, bridgeId: dataRef.bridgeId,
                //         children: null
                //     }, {
                //         title: '交安结构', checkable: false, eventType: 'chiStructure', eventKey: 'chiStructure', key: 'chiStructure' + dataRef.id, bridgeId: dataRef.bridgeId,
                //         children: null
                //     }]
                //     _this.setState({
                //         data: [..._this.state.data]
                //     })
                // } else {
                let res = await props.loadProjectBridges({ bridgeMainId: dataRef.id })
                if (res && res.length) {
                    const len4 = res.length;
                    for (let i = 0; i < len4; i++) {
                        let item = res[i];
                        item.title = item.name + '(' + (item.leftOrRight == 0 ? "左幅" : (item.leftOrRight == 1 ? '右幅' : '单幅')) + ')';
                        item.key = 'bridgeChild' + item.id;
                        item.bridgeMinId = dataRef.id
                        item.eventType = 'bridgeChild'
                        item.eventKey = 'bridgeChild'
                        item.checkable = true
                        item.selectable = true
                    }
                }
                dataRef.children = res
                if (dataRef.rg) {
                    _this.updateTreeNode(dataRef.eventKey,res)
                 }
                // _this.setState({
                //     data: [..._this.state.data]
                // })
                // }

            } else if (eventType == 'bridgeChild') {
                dataRef.children = [{
                    title: '上部结构', checkable: false, eventType: 'topStructure', eventKey: 'topStructure', key: 'topStructure' + dataRef.id, bridgeId: dataRef.id,
                    children: null
                }, {
                    title: '下部结构', checkable: false, eventType: 'botStructure', eventKey: 'botStructure', key: 'botStructure' + dataRef.id, bridgeId: dataRef.id,
                    children: null
                }, {
                    title: '附属结构', checkable: false, eventType: 'attachStructure', eventKey: 'attachStructure', key: 'attachStructure' + dataRef.id, bridgeId: dataRef.id,
                    children: null
                }, {
                    title: '交安结构', checkable: false, eventType: 'chiStructure', eventKey: 'chiStructure', key: 'chiStructure' + dataRef.id, bridgeId: dataRef.id,
                    children: null
                }]
                // _this.setState({
                //     data: [..._this.state.data]
                // })
            } else if (eventType == 'botStructure') {//下部结构
                let res = await props.getBridgeSpansById({ bridgeId: dataRef.bridgeId })
                if (res && res.length) {
                    const len5 = res.length;
                    for (let i = 0; i < len5; i++) {
                        let item = res[i];
                        item.title = item.name + ' : ' + item.code;
                        item.key = 'botStructureDirec' + item.id;
                        item.bridgeId = dataRef.bridgeId
                        item.eventType = 'botStructureDirec'
                        item.eventKey = 'botStructureDirec'
                        item.checkable = true
                        item.selectable = true
                    }
                }
                dataRef.children = res
                if (dataRef.rg) {
                    _this.updateTreeNode(dataRef.eventKey,res)
                 }
                // _this.setState({
                //     data: [..._this.state.data]
                // })
            } else if (eventType == 'botStructureDirec') {//下部结构

                let res = await props.getBotDefinitionInstanceListById({ spanId: dataRef.id })
                if (res && res.length) {
                    const len6 = res.length;
                    for (let i = 0; i < len6; i++) {
                        let item = res[i];
                        const obj = await worker.getTreeNode(structureTree, item.definitionTreeId)
                        item.title = obj.title + ":" + item.instanceName;
                        item.key = 'botStructureComponentUnit' + item.id;
                        item.spanId = dataRef.id
                        item.eventType = 'botStructureComponentUnit'
                        item.eventKey = 'botStructureComponentUnit'
                        item.checkable = true
                        item.selectable = true
                        item.isLeaf = true
                    }
                }
                dataRef.children = res
                if (dataRef.rg) {
                   _this.updateTreeNode(dataRef.eventKey,res)
                }

            } else if (eventType == 'topStructure') {//上部结构
                let res = await props.getTopDefinitionInstanceBySelectionList({ bridgeId: dataRef.bridgeId })
                if (res && res.length) {
                    const len7 = res.length;
                    for (let i = 0; i < len7; i++) {
                        let item = res[i];
                        item.title = item.listName + '(' + item.express + ')';
                        item.bridgeId = dataRef.bridgeId
                        item.key = 'topStructureDirec' + item.id;
                        item.eventType = 'topStructureDirec'
                        item.eventKey = 'topStructureDirec'
                        item.checkable = true
                        item.selectable = true
                    }
                }
                dataRef.children = res
                if (dataRef.rg) {
                    _this.updateTreeNode(dataRef.eventKey,res)
                 }
                // _this.setState({
                //     data: [..._this.state.data]
                // })

            } else if (eventType == 'topStructureDirec') {//上部结构
                let res = await props.getSectionComponents({ id: dataRef.id })

                if (res && res.length) {
                    const len8 = res.length;
                    for (let i = 0; i < len8; i++) {
                        let item = res[i];
                        const obj = await worker.getTreeNode(structureTree, item.definitionTreeId)
                        item.title = obj.title + ":" + item.instanceName;
                        item.key = 'topStructureComponentUnit' + item.id;
                        item.selectionId = dataRef.id
                        item.eventType = 'topStructureComponentUnit'
                        item.eventKey = 'topStructureComponentUnit'
                        item.checkable = true
                        item.selectable = true
                        item.isLeaf = true
                    }
                }
                dataRef.children = res
                if (dataRef.rg) {
                    _this.updateTreeNode(dataRef.eventKey,res)
                 }
                // _this.setState({
                //     data: [..._this.state.data]
                // })
            }


            // props.loadRefProjectRoads()
            resolve()
        })

    }
    onLoad(loadedKeys) {
        this.setState({
            loadedKeys
        })
    }
    getTargetNodes(data, key, remove) {//数组|字符串,remove控制删除
        let target;
        let isArray = key instanceof Array;
        let targets = []
        function oneTarget(list) {
            const len = list.length;
            for (let i = 0; i < len; i++) {
                let item = list[i];
                if (!isArray) {
                    if (item && item.key == key) {
                        target = item;
                        if (remove) {
                            list.splice(i,1)
                        }
                        break;
                    } else {
                        if (item && item.children && item.children.length) {
                            oneTarget(item.children)
                        }
                    }
                } else {
                    if (key && key.length) {
                        const len2 = key.length
                        for (let j = 0; j < len2; j++) {
                            const item2 = key[j];
                            if (item && item.key == item2) {
                                targets.push(item);
                                if (remove) {
                                    list.splice(i,1)
                                }
                                break;
                            } else {
                                if (item && item.children && item.children.length) {
                                    oneTarget(item.children)
                                }
                            }
                        }
                    }
                }

            }
            return isArray ? targets : target
        }
        return oneTarget(data)
    }
    insertTreeNode(key, obj) {//单个|多个节点插入
        let data = this.state.data;
        let target = this.getTargetNodes(data, key)
        let isArray = target instanceof Array;
        let isArray2 = obj instanceof Array;
        if (!isArray) {
            if (target) {
                if (target.children && target.children.length) {
                    if (!isArray2) {
                        if (!target.children.find(item => item && item.key == obj.key)) {
                            if (obj.type && obj.type == "top") {
                                obj.sectionId = target.id;
                            } else if (obj.type && obj.type == "bottom") {
                                obj.spanId = target.id;
                            }
                            target.children.push(obj)

                        }
                    } else {
                        if (obj && obj.length) {
                            const len = obj.length;
                            for (let i = 0; i < len; i++) {
                                let item = obj[i];

                                if (!target.children.find(item2 => item2 && item2.key == item.key)) {
                                    if (item.type && item.type == "top") {
                                        item.sectionId = target.id;
                                    } else if (item.type && item.type == "bottom") {
                                        item.spanId = target.id;
                                    }
                                    target.children.push(item)

                                }
                            }
                        }
                    }
                } else {

                    if (obj.type && obj.type == "top") {
                        obj.sectionId = target.id;
                    } else if (obj.type && obj.type == "bottom") {
                        obj.spanId = target.id;
                    }
                    // target.children = !isArray2 ? [obj] : obj
                }


            }
        } else {
            if (target && target.length) {
                for (let i = 0; i < target.length; i++) {
                    let item = target[i];
                    if (item.children && item.children.length) {
                        if (!isArray2) {
                            if (!item.children.find(item2 => item2 && item2.key == item.key)) {
                                if (obj.type && obj.type == "top") {
                                    obj.sectionId = item.id;
                                } else if (obj.type && obj.type == "bottom") {
                                    obj.spanId = item.id;
                                }
                                item.children.push(obj)
                            }
                        } else {
                            if (obj && obj.length) {
                                for (let j = 0; j < obj.length; j++) {
                                    let item2 = obj[j];
                                    if (!item.children.find(item3 => item3 && item3.key == item2.key)) {
                                        if (item2.type && item2.type == "top") {
                                            item2.sectionId = item.id;
                                        } else if (item2.type && item2.type == "bottom") {
                                            item2.spanId = item.id;
                                        }
                                        item.children.push(item2)
                                    }
                                }
                            }
                        }
                    } else {
                        if (obj.type && obj.type == "top") {
                            obj.sectionId = target.id;
                        } else if (obj.type && obj.type == "bottom") {
                            obj.spanId = target.id;
                        }
                        // item.children = !isArray2 ? [obj] : obj
                    }

                }
            }
        }
        this.loopTreeNode(this.state.data)
        this.setState({
            data: [...this.state.data]
        })
    }
    updateTreeNode(key, list) {
        let data = this.state.data;
        let target = this.getTargetNodes(data, key)
        if (target) {
            target.children = list
        }
        this.loopTreeNode(data)
        this.setState({
            data: [...data]
        })
    }
    updateTreeNodeSelf(key, values) {
        let data = this.state.data;
        let target = this.getTargetNodes(data, key)

        if (target) {
            Object.assign(target, values)
        }
        this.loopTreeNode(data)
        this.setState({
            data: [...data]
        })
    }
    removeTreeNode(keys) {
        let data = this.state.data;
        if (keys) {
            let res = this.getTargetNodes(data, keys, true)

            this.loopTreeNode(data)
            this.setState({
                data: [...data]
            })
        }

    }
    
    onExpand(expandedKeys) {
        this.setState({
            expandedKeys: expandedKeys,
            autoExpandParent: false,
        })
    }
    getIconByType(eventType) {
        let imgsrc = ""
        switch (eventType) {
            case "bridge":
                imgsrc = "./static/images/addBridge.png"
                break;
            case "topStructure":
                imgsrc = "./static/images/topStructure.png"
                break;
            case "topStructureDirec":
                imgsrc = "./static/images/topStructure.png"
                break;
            case "botStructure":
                imgsrc = "./static/images/botStructure.png"
                break;
            case "botStructureDirec":
                imgsrc = "./static/images/botStructure.png"
                break;
            case "attachStructure":
                imgsrc = "./static/images/attachComponent.png"
                break;
            case "chiStructure":
                imgsrc = "./static/images/jaStructure.png"
                break;
            default:
                imgsrc = "./static/images/libary.png"
                break;
        }
        return imgsrc;
    }
    renderTreeNodes(data) {
        return data.map(item => {
            let imgsrc = this.getIconByType(item.eventType)
            if (item.children && !item.hidden) {
                return (
                    <TreeNode icon={<img src={imgsrc} alt="" />} checkable={item.checkable} title={item.title} key={item.key} dataRef={item}>
                        {this.renderTreeNodes(item.children)}
                    </TreeNode>
                );
            }
            return !item.hidden ? <TreeNode icon={<img src={imgsrc} alt="" />} checkable={item.checkable} title={item.title} key={item.key} {...item} dataRef={item}></TreeNode> : undefined;

        });
    }
   async  componentWillMount() {
        if (this.props.onLoaded) {
            this.props.onLoaded(this);
        }
        const res=await worker.buildProjectTree(this.props.project)
        let data = [res]
        let expandedKeys = data.map(item => item.key)
        this.setState({
            data: data,
            expandedKeys: expandedKeys
        })

    }
    render() {
        let { data, expandedKeys, autoExpandParent, selectedKeys } = this.state
        return (
            <Tree icon={<img src="./static/images/libary.png" alt="" />} showIcon ref="tree" treeData={data}
                onLoad={this.onLoad}
                onExpand={this.onExpand}
                expandedKeys={expandedKeys}
                selectedKeys={selectedKeys}
                autoExpandParent={autoExpandParent}
                loadData={(e) => this.loadData(e)}
                onSelect={this.onSelect}>
                {data ? this.renderTreeNodes(data) : null}
            </Tree>
        )
    }
}
export default connect(
    ({
        dict: { structureTree }
    }) => {
        return {
            structureTree
        }
    },
    dispatch => ({
        getBridgeMainList: (values) => dispatch({
            type: 'bridge/getBridgeMainList',
            payload: values
        }),
        getComponentDetail: (values) => dispatch({
            type: 'structure/getComponentDetail',
            payload: values
        }),
        getTopDefinitionInstanceBySelectionList: (values) => dispatch({
            type: 'structure/getTopDefinitionInstanceBySelectionList',
            payload: values
        }),
        getSectionComponents: (values) => dispatch({
            type: 'structure/getSectionComponents',
            payload: values
        }),
        getTopComponent: (values) => dispatch({
            type: 'structure/getTopComponent',
            payload: values
        }),
        getComponentBySpanId: (values) => dispatch({
            type: 'structure/getComponentBySpanId',
            payload: values
        }),
        getBotStructures: (values) => dispatch({
            type: 'structure/getBotStructures',
            payload: values
        }),
        getTopStructures: (values) => dispatch({
            type: 'structure/getTopStructures',
            payload: values
        }),
        loadRefProjectRoads: (values) => dispatch({
            type: 'refRoads/loadRefProjectRoads',
            payload: values
        }),
        loadProjectBridges: (values) => dispatch({
            type: 'bridge/loadProjectBridges',
            payload: values
        }),
        getBotDefinitionInstanceListById: (values) => dispatch({
            type: 'structure/getBotDefinitionInstanceListById',
            payload: values
        }),
        getTopDefinitionInstanceListById: (values) => dispatch({
            type: 'structure/getTopDefinitionInstanceListById',
            payload: values
        }),
        getBridgeSpansById: (values) => dispatch({
            type: 'refSpans/getBridgeSpansById',
            payload: values
        }),
        getTopSelections: (values) => dispatch({
            type: 'refSpans/getTopSelections',
            payload: values
        }),
        getSelections: (values) => dispatch({
            type: 'refSpans/getSelections',
            payload: values
        }),
        queryBridgeDetail: (values) => dispatch({
            type: 'bridge/queryBridgeDetail',
            payload: values
        }),
        updateCurrentRoad: (road, onSuccess, onError) => dispatch({
            type: 'refRoads/updateCurrent',
            payload: {
                road,
                onSuccess,
                onError
            }
        }),
        updateCurrentBridge: (bridge) => dispatch({
            type: 'bridge/updateCurrent',
            payload: bridge
        }),
        updateCurrentSpan: (span, onSuccess, onError) => dispatch({
            type: 'refSpans/updateCurrent',
            payload: span
        }),
        updateCurrentProps: (props) => dispatch({
            type: 'prop/updateCurrentProps',
            payload: props
        }),
        updateActions: (actions) => dispatch({
            type: 'action/updateActions',
            payload: actions
        }),
        updateActionData: (props) => dispatch({
            type: 'action/updateActionData',
            payload: props
        }),
        RoadlineOriginData: (params) => dispatch({
            type: 'refRoads/RoadlineOriginData',
            payload: params
        })
    })
)(ProjectDirecTree)